package com.chen.q2.JdbcInsert;

import com.chen.q2.Entity.TOrder;
import com.chen.q2.snowflakes.IdWorker;
import com.chen.q2.utils.PreparedStatementSqlUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Date;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 多线程插入100W条数据，大概15秒左右
 */
@Component
public class MultiThreadInsert {
    @Autowired
    @Qualifier("dataSource")
    private DataSource dataSource;

    private CountDownLatch latch = new CountDownLatch(10);

    private IdWorker idWorker = new IdWorker(11,2,0);
    String insertOrderSql = PreparedStatementSqlUtil.generateInsertPreparedStatementSql(TOrder.class);

    public void executeOnMillionInsert() throws SQLException {

        AtomicInteger counter = new AtomicInteger(0);
        for (int i=0;i<10;i++){     //10个线程向数据库插入数据
            int c = counter.getAndIncrement();
            new Thread(()->{
                System.out.println("线程执行：" + Thread.currentThread().getName() +" "+ c) ;
                try {
                    Connection conn = dataSource.getConnection();
                    conn.setAutoCommit(false);
                    PreparedStatement pst = conn.prepareStatement(insertOrderSql);
                    TOrder order = TOrder.builder()
                            .createTime(new Date())
                            .build();
                    for (int j=0;j<10_0000;j++){    //每个线程10W条数据
                        int id = c * 10_0000 + j;
                        order.setId(Long.valueOf(id));
                        order.setOrderNo(String.valueOf(idWorker.nextId()));
                        PreparedStatementSqlUtil.setPrepareStatementParams(pst, order);
                        pst.addBatch();
                        if (j % 10000 == 0){    //每1W条数据executeBatch一次
                            pst.executeBatch();
                        }
                    }
                    pst.executeBatch();
                    conn.commit();
                    latch.countDown();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }).start();

        }
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
